/*
 * Copyright (C) 2019 Qunar, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package qunar.tc.bistoury.attach.arthas.debug;

import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.middleware.cli.annotations.Argument;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Option;
import com.taobao.middleware.logger.Logger;
import qunar.tc.bistoury.attach.common.AttachJacksonSerializer;
import qunar.tc.bistoury.attach.common.BistouryLoggger;
import qunar.tc.bistoury.common.*;

import java.util.List;
import java.util.concurrent.locks.LockSupport;

/**
 * @author zhenyu.nie created on 2018 2018/11/23 16:58
 */
@Name(BistouryConstants.REQ_DEBUG_SEARCH)
public class QDebugSearchCommand extends AnnotatedCommand {

    private static final Logger logger = BistouryLoggger.getLogger();

    private static final int SUCCESS = 0;

    private static final int NO_BREAKPOINT = 1;

    private static final int NOT_READY = 2;

    private static final int CONDITION_FAIL = 3;

    private String id;

    /**
     * 调用debug的页面id，批量添加多个断点时，根据页面id返回当前页面所有的断点。每次打开debug的页面都会生成一个新的页面id
     */
    private String callDebugPageId;

    @Argument(index = 0, argName = "id")
    public void setId(String id) {
        this.id = id;
    }

    @Option(shortName = "p", longName = "callDebugPageId")
    public void setCallDebugPageId(String callDebugPageId) {
        this.callDebugPageId = callDebugPageId;
    }

    @Override
    public void process(CommandProcess process) {
        logger.info("receive debug search command, id [" + id + "]");
        CodeProcessResponse<Snapshot> codeResponse = new CodeProcessResponse<>();
        TypeResponse<Snapshot> typeResponse = new TypeResponse<>();
        typeResponse.setType(BistouryConstants.REQ_DEBUG_SEARCH);
        typeResponse.setData(codeResponse);
        try {
            QDebugClient client = QDebugClients.getInstance();
            Snapshot snapshot = client.getSnapshot(id);
            codeResponse.setId(id);
            if (snapshot == null) {
                codeResponse.setCode(NO_BREAKPOINT);
            } else if (snapshot.isInit()) {
                synchronized (callDebugPageId) {
                    System.out.println("页面id:" + callDebugPageId);
                    if (snapshot.getTotalHitBreakpointNum() == null) {
                        //循环等待线程处理完所有断点，（即处理所有断点的线程不再是runnable状态，所有断点用的是同一线程）
                        while (Thread.State.RUNNABLE.equals(snapshot.getCurrentThread().getState())) {
                            //TODO 优化等待策略
                            LockSupport.parkNanos(1);
                        }
                        List<Snapshot> snapshotList = client.getSnapshotList(snapshot.getCallDebugPageId());
                        System.out.println("查询出来的结果：" + snapshotList.size());
                    }
                }
                codeResponse.setCode(SUCCESS);
                codeResponse.setData(snapshot);
            } else if (snapshot.isFail()) {
                codeResponse.setCode(CONDITION_FAIL);
            } else {
                codeResponse.setCode(NOT_READY);
            }
        } catch (Throwable e) {
            logger.error("qdebug-search-error", e.getMessage(), e);
            codeResponse.setId(id);
            codeResponse.setCode(-1);
            codeResponse.setMessage(e.getMessage());
        }

        process.write(URLCoder.encode(AttachJacksonSerializer.serialize(typeResponse)));
        process.end();
    }

    public static void main(String[] args) {
//        String jsonStr = URLCoder.decode("%7B%22type%22%3A%22qdebugsearch%22%2C%22data%22%3A%7B%22id%22%3A%22e177b37f-11d4-4d65-b026-27dc11fd8243-n%22%2C%22code%22%3A0%2C%22data%22%3A%7B%22id%22%3A%22e177b37f-11d4-4d65-b026-27dc11fd8243-n%22%2C%22source%22%3A%22com%2Flc%2Fmock%2Fallmethod%2Fsample%2Fcontroller%2FTestSampleController.java%22%2C%22line%22%3A38%2C%22staticFields%22%3A%7B%22log%22%3A%22%7B%5C%22%40qdebug_id%5C%22%3A1%2C%5C%22name%5C%22%3A%5C%22com.lc.mock.allmethod.sample.controller.TestSampleController%5C%22%7D%22%7D%2C%22fields%22%3A%7B%22testSampleService%22%3A%22%7B%5C%22%40qdebug_id%5C%22%3A1%7D%22%7D%2C%22localVariables%22%3A%7B%22this%22%3A%22%7B%5C%22%40qdebug_id%5C%22%3A1%2C%5C%22testSampleService%5C%22%3A%7B%5C%22%40qdebug_id%5C%22%3A2%7D%7D%22%2C%22resp%22%3A%22%7B%5C%22%40qdebug_id%5C%22%3A1%2C%5C%22count%5C%22%3A3%2C%5C%22tagId%5C%22%3A%5C%22f8bf64d7-a1d6-458c-bc15-54ed98a80113%5C%22%2C%5C%22msg%5C%22%3Anull%7D%22%2C%22req%22%3A%22%7B%5C%22%40qdebug_id%5C%22%3A1%2C%5C%22id%5C%22%3A%5C%22sunt+deserunt+esse%5C%22%7D%22%7D%2C%22stacktrace%22%3A%22%5B%7B%5C%22%40qdebug_id%5C%22%3A1%2C%5C%22declaringClass%5C%22%3A%5C%22com.lc.mock.allmethod.sample.controller.TestSampleController%5C%22%2C%5C%22methodName%5C%22%3A%5C%22test%5C%22%2C%5C%22fileName%5C%22%3A%5C%22TestSampleController.java%5C%22%2C%5C%22lineNumber%5C%22%3A38%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A2%2C%5C%22declaringClass%5C%22%3A%5C%22sun.reflect.NativeMethodAccessorImpl%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke0%5C%22%2C%5C%22fileName%5C%22%3A%5C%22NativeMethodAccessorImpl.java%5C%22%2C%5C%22lineNumber%5C%22%3A-2%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A3%2C%5C%22declaringClass%5C%22%3A%5C%22sun.reflect.NativeMethodAccessorImpl%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22NativeMethodAccessorImpl.java%5C%22%2C%5C%22lineNumber%5C%22%3A62%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A4%2C%5C%22declaringClass%5C%22%3A%5C%22sun.reflect.DelegatingMethodAccessorImpl%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22DelegatingMethodAccessorImpl.java%5C%22%2C%5C%22lineNumber%5C%22%3A43%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A5%2C%5C%22declaringClass%5C%22%3A%5C%22java.lang.reflect.Method%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22Method.java%5C%22%2C%5C%22lineNumber%5C%22%3A498%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A6%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.method.support.InvocableHandlerMethod%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doInvoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22InvocableHandlerMethod.java%5C%22%2C%5C%22lineNumber%5C%22%3A205%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A7%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.method.support.InvocableHandlerMethod%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invokeForRequest%5C%22%2C%5C%22fileName%5C%22%3A%5C%22InvocableHandlerMethod.java%5C%22%2C%5C%22lineNumber%5C%22%3A150%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A8%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invokeAndHandle%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ServletInvocableHandlerMethod.java%5C%22%2C%5C%22lineNumber%5C%22%3A117%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A9%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invokeHandlerMethod%5C%22%2C%5C%22fileName%5C%22%3A%5C%22RequestMappingHandlerAdapter.java%5C%22%2C%5C%22lineNumber%5C%22%3A895%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A10%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22handleInternal%5C%22%2C%5C%22fileName%5C%22%3A%5C%22RequestMappingHandlerAdapter.java%5C%22%2C%5C%22lineNumber%5C%22%3A808%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A11%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22handle%5C%22%2C%5C%22fileName%5C%22%3A%5C%22AbstractHandlerMethodAdapter.java%5C%22%2C%5C%22lineNumber%5C%22%3A87%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A12%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.DispatcherServlet%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doDispatch%5C%22%2C%5C%22fileName%5C%22%3A%5C%22DispatcherServlet.java%5C%22%2C%5C%22lineNumber%5C%22%3A1070%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A13%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.DispatcherServlet%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doService%5C%22%2C%5C%22fileName%5C%22%3A%5C%22DispatcherServlet.java%5C%22%2C%5C%22lineNumber%5C%22%3A963%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A14%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.FrameworkServlet%5C%22%2C%5C%22methodName%5C%22%3A%5C%22processRequest%5C%22%2C%5C%22fileName%5C%22%3A%5C%22FrameworkServlet.java%5C%22%2C%5C%22lineNumber%5C%22%3A1006%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A15%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.FrameworkServlet%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doPost%5C%22%2C%5C%22fileName%5C%22%3A%5C%22FrameworkServlet.java%5C%22%2C%5C%22lineNumber%5C%22%3A909%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A16%2C%5C%22declaringClass%5C%22%3A%5C%22javax.servlet.http.HttpServlet%5C%22%2C%5C%22methodName%5C%22%3A%5C%22service%5C%22%2C%5C%22fileName%5C%22%3A%5C%22HttpServlet.java%5C%22%2C%5C%22lineNumber%5C%22%3A681%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A17%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.servlet.FrameworkServlet%5C%22%2C%5C%22methodName%5C%22%3A%5C%22service%5C%22%2C%5C%22fileName%5C%22%3A%5C%22FrameworkServlet.java%5C%22%2C%5C%22lineNumber%5C%22%3A883%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A18%2C%5C%22declaringClass%5C%22%3A%5C%22javax.servlet.http.HttpServlet%5C%22%2C%5C%22methodName%5C%22%3A%5C%22service%5C%22%2C%5C%22fileName%5C%22%3A%5C%22HttpServlet.java%5C%22%2C%5C%22lineNumber%5C%22%3A764%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A19%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22internalDoFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A227%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A20%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A162%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A21%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.tomcat.websocket.server.WsFilter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22WsFilter.java%5C%22%2C%5C%22lineNumber%5C%22%3A53%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A22%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22internalDoFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A189%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A23%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A162%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A24%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.filter.RequestContextFilter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilterInternal%5C%22%2C%5C%22fileName%5C%22%3A%5C%22RequestContextFilter.java%5C%22%2C%5C%22lineNumber%5C%22%3A100%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A25%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.filter.OncePerRequestFilter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22OncePerRequestFilter.java%5C%22%2C%5C%22lineNumber%5C%22%3A117%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A26%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22internalDoFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A189%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A27%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A162%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A28%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.filter.FormContentFilter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilterInternal%5C%22%2C%5C%22fileName%5C%22%3A%5C%22FormContentFilter.java%5C%22%2C%5C%22lineNumber%5C%22%3A93%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A29%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.filter.OncePerRequestFilter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22OncePerRequestFilter.java%5C%22%2C%5C%22lineNumber%5C%22%3A117%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A30%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22internalDoFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A189%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A31%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A162%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A32%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.filter.CharacterEncodingFilter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilterInternal%5C%22%2C%5C%22fileName%5C%22%3A%5C%22CharacterEncodingFilter.java%5C%22%2C%5C%22lineNumber%5C%22%3A201%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A33%2C%5C%22declaringClass%5C%22%3A%5C%22org.springframework.web.filter.OncePerRequestFilter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22OncePerRequestFilter.java%5C%22%2C%5C%22lineNumber%5C%22%3A117%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A34%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22internalDoFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A189%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A35%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.ApplicationFilterChain%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doFilter%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ApplicationFilterChain.java%5C%22%2C%5C%22lineNumber%5C%22%3A162%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A36%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.StandardWrapperValve%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22StandardWrapperValve.java%5C%22%2C%5C%22lineNumber%5C%22%3A197%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A37%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.StandardContextValve%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22StandardContextValve.java%5C%22%2C%5C%22lineNumber%5C%22%3A97%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A38%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.authenticator.AuthenticatorBase%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22AuthenticatorBase.java%5C%22%2C%5C%22lineNumber%5C%22%3A541%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A39%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.StandardHostValve%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22StandardHostValve.java%5C%22%2C%5C%22lineNumber%5C%22%3A135%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A40%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.valves.ErrorReportValve%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ErrorReportValve.java%5C%22%2C%5C%22lineNumber%5C%22%3A92%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A41%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.core.StandardEngineValve%5C%22%2C%5C%22methodName%5C%22%3A%5C%22invoke%5C%22%2C%5C%22fileName%5C%22%3A%5C%22StandardEngineValve.java%5C%22%2C%5C%22lineNumber%5C%22%3A78%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A42%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.catalina.connector.CoyoteAdapter%5C%22%2C%5C%22methodName%5C%22%3A%5C%22service%5C%22%2C%5C%22fileName%5C%22%3A%5C%22CoyoteAdapter.java%5C%22%2C%5C%22lineNumber%5C%22%3A360%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A43%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.coyote.http11.Http11Processor%5C%22%2C%5C%22methodName%5C%22%3A%5C%22service%5C%22%2C%5C%22fileName%5C%22%3A%5C%22Http11Processor.java%5C%22%2C%5C%22lineNumber%5C%22%3A399%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A44%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.coyote.AbstractProcessorLight%5C%22%2C%5C%22methodName%5C%22%3A%5C%22process%5C%22%2C%5C%22fileName%5C%22%3A%5C%22AbstractProcessorLight.java%5C%22%2C%5C%22lineNumber%5C%22%3A65%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A45%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.coyote.AbstractProtocol%24ConnectionHandler%5C%22%2C%5C%22methodName%5C%22%3A%5C%22process%5C%22%2C%5C%22fileName%5C%22%3A%5C%22AbstractProtocol.java%5C%22%2C%5C%22lineNumber%5C%22%3A890%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A46%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.tomcat.util.net.NioEndpoint%24SocketProcessor%5C%22%2C%5C%22methodName%5C%22%3A%5C%22doRun%5C%22%2C%5C%22fileName%5C%22%3A%5C%22NioEndpoint.java%5C%22%2C%5C%22lineNumber%5C%22%3A1789%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A47%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.tomcat.util.net.SocketProcessorBase%5C%22%2C%5C%22methodName%5C%22%3A%5C%22run%5C%22%2C%5C%22fileName%5C%22%3A%5C%22SocketProcessorBase.java%5C%22%2C%5C%22lineNumber%5C%22%3A49%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A48%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.tomcat.util.threads.ThreadPoolExecutor%5C%22%2C%5C%22methodName%5C%22%3A%5C%22runWorker%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ThreadPoolExecutor.java%5C%22%2C%5C%22lineNumber%5C%22%3A1191%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A49%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.tomcat.util.threads.ThreadPoolExecutor%24Worker%5C%22%2C%5C%22methodName%5C%22%3A%5C%22run%5C%22%2C%5C%22fileName%5C%22%3A%5C%22ThreadPoolExecutor.java%5C%22%2C%5C%22lineNumber%5C%22%3A659%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A50%2C%5C%22declaringClass%5C%22%3A%5C%22org.apache.tomcat.util.threads.TaskThread%24WrappingRunnable%5C%22%2C%5C%22methodName%5C%22%3A%5C%22run%5C%22%2C%5C%22fileName%5C%22%3A%5C%22TaskThread.java%5C%22%2C%5C%22lineNumber%5C%22%3A61%7D%2C%7B%5C%22%40qdebug_id%5C%22%3A51%2C%5C%22declaringClass%5C%22%3A%5C%22java.lang.Thread%5C%22%2C%5C%22methodName%5C%22%3A%5C%22run%5C%22%2C%5C%22fileName%5C%22%3A%5C%22Thread.java%5C%22%2C%5C%22lineNumber%5C%22%3A750%7D%5D%22%2C%22expireTime%22%3A1746074086449%7D%2C%22message%22%3Anull%7D%7D");
//        System.out.println(jsonStr);
//        int i=0;
//        while (Thread.State.RUNNABLE.equals(Thread.currentThread().getState())) {
//            //TODO 优化等待策略
//            LockSupport.parkNanos(1);
//            System.out.println("等待");
//        }
//        System.out.println(i);
        byte[] total = "我".getBytes();
        byte[] bytes = "12345".getBytes();

        byte[] newData = new byte[total.length + bytes.length];
        System.arraycopy(total, 0, newData, 0, total.length);
        System.arraycopy(bytes, 0, newData, total.length, bytes.length);
        total = newData;

        System.out.println(new String(total));

        Snapshot snapshot = new Snapshot("", "", 3, 3);
        System.out.println(snapshot.getTotalHitBreakpointNum());
    }
}
